package top.techqi.app.wol

import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import androidx.room.Room
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import top.techqi.app.wol.db.AppDatabase
import top.techqi.app.wol.db.dao.DeviceDao
import top.techqi.app.wol.db.tbl.Device
import top.techqi.base.App
import java.net.DatagramPacket
import java.net.DatagramSocket
import java.net.InetAddress

class MainViewModel : ViewModel() {
    private lateinit var db: AppDatabase

    val devices = MutableLiveData<List<Device>>()

    override fun onCleared() {
        if (::db.isInitialized) db.close()
        super.onCleared()
    }

    fun refreshDevice() {
        viewModelScope.launch {
            val dao = ensureDao()
            val result = dao.getAllDevices()
            devices.postValue(result)
        }
//        val list = listOf(
//            Device(1, "", "z", "00:F1:F3:1A:CD:00"),
//            Device(1, "", "z", "f"),
//            Device(1, "", "z", "f"),
//            Device(1, "", "z", "f"),
//            Device(1, "", "z", "f"),
//            Device(1, "", "z", "f"),
//            Device(1, "", "z", "f"),
//            Device(1, "", "z", "f"),
//            Device(1, "", "z", "f"),
//            Device(1, "", "z", "f"),
//            Device(1, "", "z", "f"),
//            Device(1, "", "z", "f"),
//            Device(1, "", "z", "f"),
//            Device(1, "", "z", "f"),
//            Device(1, "", "z", "f"),
//            Device(1, "", "z", "f"),
//            Device(1, "", "z", "f"),
//            Device(1, "", "z", "f"),
//            Device(1, "", "z", "f"),
//        )
//        devices.value = list
    }

    fun appendDevice(icon: String?, name: String, addr: String) {
        viewModelScope.launch {
            val dao = ensureDao()
            dao.addDevice(Device(0, icon, name, addr))
            refreshDevice()
        }
    }

    fun updateDevice(id: Int, icon: String?, name: String, addr: String) {
        viewModelScope.launch {
            val dao = ensureDao()
            dao.updateDevice(id, icon, name, addr)
            refreshDevice()
        }
    }

    fun getDeviceById(id: Int): Device? {
        return devices.value?.find { it.id == id }
    }

    fun removeDevice(id: Int) {
        viewModelScope.launch {
            val dao = ensureDao()
            dao.delDevice(id)
            refreshDevice()
        }
    }

    fun x(addr: String) {
        val x = addr.split(':', '-').map { it.toUByte(16).toByte() }.toByteArray()
        val bytes = ByteArray(102) { 0xff.toByte() }
        repeat(16) {
            System.arraycopy(x, 0, bytes, (it + 1) * 6, 6)
        }

        viewModelScope.launch(Dispatchers.IO) {
            val packet = DatagramPacket(bytes, bytes.size)
            packet.address = InetAddress.getByName("255.255.255.255")
            val socket = DatagramSocket()
            socket.broadcast = true
            socket.send(packet)
            socket.close()
        }
    }

    private fun ensureDao(): DeviceDao {
        if (!::db.isInitialized) {
            db = Room.databaseBuilder(App.INSTANCE, AppDatabase::class.java, "app").build()
        }
        return db.deviceDao()
    }
}